package com.ibm.crl.sb.thread.typicalexam.philosophers;

/**
 * 哲学家进餐问题
 * 
 * @author soft
 * 
 */
public class Scientist extends Thread {
	/*
	 * @author：Bore
	 * 
	 * @mail：zhaogangtao@gmail.com
	 * 
	 * @time：2010/12/7 1.哲学家进餐，5个哲学家，5只筷子 2.哲学家通过getChopsticks()方法，来取筷子。
	 * 3.当哲学家同时获得左边和右边两只筷子后才可以进餐。否则把已经得到的筷子也释放 4.如果一直筷子也没有，进程阻塞，等待其他哲学家释放资源
	 * 5.进程后，释放已经获得的资源
	 */

	static byte[] chopsticks = { 1, 1, 1, 1, 1 };// 五只筷子

	public Scientist(String name) {
		super(name);
	}

	public void run() {
		getChopsticks();
	}

	public void getChopsticks() {// 开始抢筷子
		int tem = Integer.parseInt(this.getName().substring(3));// 获取哲学家编号
		if (tem == 0) {// 如果是第一位科学家，先抢左边的筷子
			if (leftChopsticks(tem)) {// 如何获取了左边的筷子
				if (rightChopsticks(tem)) {// 如果获取了右边的筷子
					eating();// 开始吃饭
					freeLeftChopsticks(tem);// 释放左边筷子
					freeRightChopsticks(tem);// 释放右边筷子
				} else {
					freeLeftChopsticks(tem);
					System.out.println("由于" + this.getName()
							+ "无法获得右手边的筷子，所以他把已获得的左手的筷子也释放了！");
					try {
						this.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					getChopsticks();
				}
			} else {
				System.out.println(this.getName() + "暂时无法获取两只筷子，准备休眠！");
				try {
					this.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				getChopsticks();

			}
		} else {// 其他情况先抢右边的筷子
			if (rightChopsticks(tem)) {// 先抢右手边的筷子。
				if (leftChopsticks(tem)) {// 如果获得了右手边的。去抢左手边的筷子。
					eating();// 如果获得了两只筷子，开始吃饭
					freeLeftChopsticks(tem);// 吃完了。释放左手边的筷子
					freeRightChopsticks(tem);// 释放右手边的筷子
				} else {
					freeRightChopsticks(tem);
					System.out.println("由于" + this.getName()
							+ "无法获得左手边的筷子，所以他把已获得的右手的筷子也释放了！");
					try {
						this.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					getChopsticks();
				}
			} else {
				System.out.println(this.getName() + "暂时无法获取两只筷子，准备休眠！");
				try {
					this.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				getChopsticks();
			}
		}

	}

	public boolean leftChopsticks(int tem) {// 获取左手边筷子
		if (chopsticks[tem] == 1) {
			chopsticks[tem] = 0;
			System.out.println(this.getName() + "左手边筷子已获得！");
			return true;
		} else {
			System.out.println(this.getName() + "左手边筷子已被哲学家" + (tem - 1)
					+ "抢走！");
			return false;
		}
	}

	public boolean rightChopsticks(int tem) {// 获取右手边筷子
		int i = (tem + 1) % 5;
		if (chopsticks[i] == 1) {
			chopsticks[i] = 0;
			System.out.println(this.getName() + "右手边筷子已获得！");
			return true;
		} else {
			System.out.println(this.getName() + "右手边筷子已被哲学家" + i + "抢走！");
			return false;
		}
	}

	public void freeLeftChopsticks(int tem) {// 获取左手边筷子
		chopsticks[tem] = 1;
		System.out.println(this.getName() + "左手边筷子已释放！");
	}

	public void freeRightChopsticks(int tem) {// 获取右手边筷子
		int i = (tem + 1) % 5;
		chopsticks[i] = 1;
		System.out.println(this.getName() + "右手边筷子已释放！");
	}

	public void eating() {// 开始进餐
		System.out.println("*" + this.getName() + "两只手都有了筷子，所以开始吃饭！");
	}

	/**
	 * 主函数
	 */
	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			new Scientist("哲学家" + i).start();
		}
	}

}